#!/bin/bash
export PATH=$PATH:/usr/local/sbin:/usr/local/bin


[ -z ${service} ] && service=mesh-service
[ -z ${secret} ] && secret=mesh-secret
[ -z ${namespace} ] && namespace=mesh-ns

if [ ! -x "$(command -v openssl)" ]; then
    echo "openssl not found"
    exit 1
fi

csrName=${service}.${namespace}
tmpdir=/home/testcert

echo "creating certs in tmpdir ${tmpdir} "


if [ ! -d ${tmpdir} ]; then
mkdir ${tmpdir}

cat > ${tmpdir}/csr.conf <<EOF
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = CN
ST = HangZhou
L = LA
O = Personal
OU = King
CN = 192.168.1.99

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
IP.1 = 192.168.1.99

[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
EOF

openssl req -x509 -nodes -new -sha256 -days 3650 -newkey rsa:2048 -subj "/CN=${service}.${namespace}.svc" \
  -keyout ${tmpdir}/ca.key \
  -out ${tmpdir}/ca.crt
openssl genrsa -out ${tmpdir}/server.key 2048
openssl req -new -key ${tmpdir}/server.key -out ${tmpdir}/server.csr -config ${tmpdir}/csr.conf
openssl x509 -req -in ${tmpdir}/server.csr -CA ${tmpdir}/ca.crt -CAkey ${tmpdir}/ca.key \
  -CAcreateserial -out ${tmpdir}/server.crt -days 3650 \
  -extensions v3_ext -extfile ${tmpdir}/csr.conf
fi


kubectl create secret generic ${secret} -n ${namespace} \
    --from-file=${tmpdir}/ca.crt \
    --from-file=${tmpdir}/server.key \
    --from-file=${tmpdir}/server.crt

cat > install.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: mesh-service
  namespace: ${namespace}
spec:
  selector:
    app: mesh
  ports:
    - port: 30808
      targetPort: 30808
      nodePort: 30808
  type: NodePort
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mesh-sa
  namespace: ${namespace}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: mesh-role
rules:
  - apiGroups: [""]
    resources: ["pods","nodes","configmaps","secret","serviceaccounts","services"]
    verbs: ["*"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["*"]
  - apiGroups: ["batch"]
    resources: ["job"]
    verbs: ["get","list","watch","update","create"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["roles","rolebindings"]
    verbs: ["get","list","watch","update","create"]
  - apiGroups: ["king.io"]
    resources: ["meshes","meshes/status"]
    verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: mesh-bind
subjects:
  - kind: ServiceAccount
    name: mesh-sa
    namespace: ${namespace}
roleRef:
  kind: ClusterRole
  name: mesh-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: meshes.king.io
spec:
  group: king.io
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                template:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true
                resources:
                  items:
                    properties:
                      protocol:
                        default: json
                        type: string
                      network:
                        type: string
                      timeout:
                        type: integer
                      path:
                        type: string
                      version:
                        type: string
                    type: object
                  type: array
                count:
                  type: integer
                port:
                  type: integer
                version:
                  type: string
            status:
              type: object
              properties:
                links:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true
                status:
                  default: build
                  type: string
                replicas:
                  type: integer
      additionalPrinterColumns:
        - jsonPath: .spec.count
          name: count
          type: integer
        - name: namespace
          type: string
          jsonPath: .metadata.namespace
        - name: image
          type: string
          jsonPath: .spec.template.spec.containers[:].image
        - name: status
          type: string
          jsonPath: .status.status
      subresources:
        status: {}
  names:
    plural: meshes
    singular: mesh
    kind: Mesh
    shortNames:
      - ms
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
    name: egresses.king.io
spec:
    group: king.io
    scope: Cluster
    versions:
      - name: v1
        served: true
        storage: true
        schema:
          openAPIV3Schema:
            type: object
            properties:
              spec:
                type: object
                properties:
                  resources:
                    type: array
                    items:
                      type: string
        additionalPrinterColumns:
          - name: resources
            type: string
            jsonPath: .spec.resources[:]
    names:
      plural: egresses
      singular: egress
      kind: Egress
      shortNames:
         - eg
EOF

cat >> install.yaml <<EOF
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: mesh-webhook
  namespace: ${namespace}
  labels:
    app: mesh-webhook
webhooks:
  - name: ${service}.${namespace}.svc
    clientConfig:
          url: "https://192.168.1.99:30808/mesh-mutating"
          caBundle: $(kubectl get secret ${secret} -n ${namespace} -o jsonpath='{.data.ca\.crt}')
    rules:
      - apiGroups: [ "king.io" ]
        apiVersions: [ "v1" ]
        operations: [ "CREATE","UPDATE" ]
        resources: [ "meshes" ]
        scope: "*"
    admissionReviewVersions: ["v1", "v1beta1"]
    sideEffects: None
    timeoutSeconds: 10
EOF


kubectl apply -f install.yaml